package org.jeecg.modules.rental.mq.handler;

import com.rabbitmq.client.Channel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.boot.starter.lock.client.RedissonLockClient;
import org.jeecg.boot.starter.rabbitmq.core.BaseRabbiMqHandler;
import org.jeecg.boot.starter.rabbitmq.listenter.MqListener;
import org.jeecg.common.annotation.RabbitComponent;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.rental.mq.service.RentalEBIkeOrderService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;

/**
 * @author by sean
 * @desc: 租车支付处理
 * @since 2024-09-24 星期二 15:04:08
 */
@Slf4j
@RequiredArgsConstructor
@RabbitComponent(value = "rental.ebike.pay.successListener")
public class RentalEBikePayHandler extends BaseRabbiMqHandler<BaseMap> {
    private final RedissonLockClient redissonLock;
    private final RentalEBIkeOrderService rentalEBIkeOrderService;

    @RabbitListener(queues = "rental.ebike.pay.success")
    public void onMessage(BaseMap baseMap, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        super.onMessage(baseMap, deliveryTag, channel, new MqListener<BaseMap>() {
            @Override
            public void handler(BaseMap map, Channel channel) {
                Long orderId = map.get("orderId");

                if (oConvertUtils.isEmpty(orderId)) {
                    log.error("orderId 为空");
                    return;
                }

                String tenantId = map.get("tenantId");
                if (oConvertUtils.isEmpty(orderId)) {
                    log.error("tenantId 为空");
                    return;
                }
                TenantContext.setTenant(tenantId);
                try{
                    String redisLockKey = "mq:ebike:order:lock" + orderId;
                    if (redissonLock.tryLock(redisLockKey, 3)) {
                        try {
                            rentalEBIkeOrderService.processOrder(orderId, map);
                        } finally {
                            redissonLock.unlock(redisLockKey);
                        }
                    } else {
                        log.warn("获取锁失败, 订单应该 {} 正在处理中，跳过本次处理", orderId);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    throw new RuntimeException("消息处理失败: " + e.getMessage(), e);
                }finally {
                    TenantContext.clear();
                }
            }
        });
    }
}
